package com.x.provider.customer.service.directory;

import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.x.provider.api.customer.model.dto.directory.AttributeRandomReqDTO;
import com.x.provider.customer.mapper.AttributeMapper;
import com.x.provider.customer.mapper.AttributeValueMapper;
import com.x.provider.customer.model.domain.directory.Attribute;
import com.x.provider.customer.model.domain.directory.AttributeValue;
import com.x.provider.customer.model.query.directory.AttributeQuery;
import com.x.provider.customer.model.query.directory.AttributeValueQuery;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class AttributeServiceImpl implements AttributeService{

    private final AttributeMapper attributeMapper;
    private final AttributeValueMapper attributeValueMapper;

    public AttributeServiceImpl(AttributeMapper attributeMapper,
                                AttributeValueMapper attributeValueMapper){
        this.attributeMapper = attributeMapper;
        this.attributeValueMapper = attributeValueMapper;
    }

    @Override
    public List<Attribute> listAttribute(List<String> nameList) {
        return list(AttributeQuery.builder().nameSystemList(nameList).build());
    }

    @Override
    public List<Attribute> listAttribute(String name) {
        return list(AttributeQuery.builder().nameSystem(name).build());
    }

    @Override
    public List<AttributeValue> listAttributeValue(List<Long> attributeIdList) {
        return list(AttributeValueQuery.builder().attributeIdList(attributeIdList).build());
    }

    @Override
    public List<AttributeValue> listAttributeValue(Long attributeId) {
        return list(AttributeValueQuery.builder().attributeId(attributeId).build());
    }

    @Override
    public Map<String, List<AttributeValue>> listAttributeValueByName(List<String> attributeNameList) {
        List<Attribute> attributeList = listAttribute(attributeNameList);
        return listAttributeValue(attributeList.stream().map(item -> item.getId()).collect(Collectors.toList())).stream().collect(Collectors.groupingBy(item -> item.getName()));
    }

    @Override
    public List<Attribute> listAttribute() {
        return list(AttributeQuery.builder().build());
    }

    @Override
    public List<AttributeValue> listAttributeValue() {
        return list(AttributeValueQuery.builder().build());
    }

    @Override
    public List<AttributeValue> randomAttribute(AttributeRandomReqDTO req) {
        List<AttributeValue> candidate = listAttributeValue(req.getName());
        if (candidate.isEmpty() || candidate.size() <= req.getTotal()){
            return candidate;
        }
        return RandomUtil.randomEleSet(candidate, req.getTotal()).stream().collect(Collectors.toList());
    }

    private List<Attribute> list(AttributeQuery query){
        return attributeMapper.selectList(build(query));
    }

    private List<AttributeValue> list(AttributeValueQuery query){
        return attributeValueMapper.selectList(build(query));
    }

    public Attribute getAttribute(AttributeQuery query){
        return attributeMapper.selectOne(build(query));
    }

    public List<AttributeValue> listAttributeValue(String attributeName){
        return listAttributeValueByName(Arrays.asList(attributeName)).get(attributeName);
    }

    private LambdaQueryWrapper<Attribute> build(AttributeQuery query){
        LambdaQueryWrapper<Attribute> queryWrapper = new LambdaQueryWrapper<>();
        if (query.getNameSystem() != null){
            queryWrapper.eq(Attribute::getNameSystem, query.getNameSystem());
        }
        if (!CollectionUtils.isEmpty(query.getNameSystemList())){
            queryWrapper.in(Attribute::getNameSystem, query.getNameSystemList());
        }
        return queryWrapper;
    }

    private LambdaQueryWrapper<AttributeValue> build(AttributeValueQuery query){
        LambdaQueryWrapper<AttributeValue> queryWrapper = new LambdaQueryWrapper<>();
        if (query.getAttributeId() != null){
            queryWrapper.eq(AttributeValue::getAttributeId, query.getAttributeId());
        }
        if (!CollectionUtils.isEmpty(query.getAttributeIdList())){
            queryWrapper.in(AttributeValue::getAttributeId, query.getAttributeId());
        }
        return queryWrapper;
    }
}
